_package("alz.core");

_import("alz.core.EventTarget");
_import("alz.core.Plugin");

/**
 * 全局事件管理者
 */
_class("EventManager", Plugin, function(){
	EventManager._uid = 1;
	//this._optionsRe = /^(?:capture|scope|delay|buffer|single|stopEvent|disableLocking|preventDefault|stopPropagation|normalized|args|delegate|horizontal|vertical|dragThreshold|holdThreshold|doubleTapThreshold|cancelThreshold|singleTapThreshold|fireClickEvent)$/;
	this._touchRe = /^(?:pinch|pinchstart|pinchend|tap|singletap|doubletap|swipe|swipeleft|swiperight|drag|dragstart|dragend|touchdown|touchstart|touchmove|touchend|taphold|tapstart|tapcancel)$/i;
	this._init = function(){
		_super._init.call(this);
		this._handler = null;
		this._types = runtime.isTouch
			? ["touchstart", "touchmove", "touchend"]
			: ["mousedown", "mousemove", "mouseup"];
		this._listeners = {};
		this._captureElement = null;
		this._down = false;
		//this._move = false;
		this._timer = 0;
		this._activeComponent = null;
		this._cancelThreshold = 10;  //超过该距离限制，TabCancel将被触发
	};
	this.create = function(name, app){
		_super.create.apply(this, arguments);
		/*
		var _this = this;
		this._handler = function(ev){
			return _this.handleEvent(ev);
		};
		for(var i = 0, len = this._types.length; i < len; i++){
			//this._self["on" + this._types[i]] = handle;
			//document.addEventListener(this._types[i], this._handler, false);
		}
		if(flag){
			this.addGlobalListener(this._self, "touchend", this, function(ev){
				return this.onTouchEnd(ev);
			});
		}
		*/
	};
	this.dispose = function(){
		this._captureElement = null;
		for(var i = 0, len = this._types.length; i < len; i++){
			//this._self["on" + this._types[i]] = null;
			//document.removeEventListener(this._types[i], this._handler, false);
		}
		/*
		if(flag){
			this.removeGlobalListener(this._self, "touchend", this);
		}
		*/
		_super.dispose.apply(this);
	};
	/**
	 * 给组件内的DOM元素或子组件添加事件
	 * @param {HTMLElement|EventTarget} obj 要添加事件的对象
	 * @param {String} type 事件类型
	 * @param {Object} agent 事件代理对象
	 * @param {String|Function} func 事件响应函数
	 */
	this.addListener = function(obj, type, agent, func){
		var cbid = runtime._task.add(agent, func, null, "event");
		if(runtime.ie && obj.tagName || obj instanceof HTMLElement){
			var listeners = runtime._element.data(obj, "listeners");
			if(!listeners){
				listeners = runtime._element.data(obj, "listeners", {});
			}
			var touch = this._touchRe.test(type);
			var listener = {
				"obj" : obj,
				"cbid": cbid,
				"wrap": this.createListenerWrap(obj, type, cbid, touch)
			};
			listeners[type] = listener;
			if(touch){
				runtime._gestureManager.addEventListener(obj, type, listener);
			}else{
				obj.addEventListener(type, listener.wrap, false);
			}
		}else if(obj instanceof EventTarget){
			//obj.addEventListener(type, agent, false);
			var listener = {
				"obj" : obj,
				"cbid": cbid,
				"wrap": this.createListenerWrap(obj, type, cbid)
			};
			obj.addEventListener(type, listener, false);
		}
	};
	/**
	 * 移除组件内的DOM元素或子组件绑定的事件
	 * @param {HTMLElement|EventTarget} obj 要添加事件的对象
	 * @param {String} type 事件类型
	 */
	this.removeListener = function(obj, type){
		if(obj instanceof Element){
			var listeners = runtime._element.data(obj, "listeners");
			if(listeners){
				var listener = listeners[type];
				for(var k in listener){
					listener[k] = null;  //obj,cbid,wrap
				}
				delete listeners[type];
			}
		}else if(obj instanceof EventTarget){
			obj.removeEventListener(type);  //移除所有type类型事件
		}
	};
	this.createListenerWrap = function(dom, type, cbid, touch){
		return function(ev, args){
			if(touch){
				ev = new TouchEventObjectImpl(ev);
			}/*else{
				ev = Ext.EventObject.setEvent(ev);
			}*/
			runtime._task.execute(cbid, [ev]);
		};
	};
	/*
	this.handleEvent = function(ev){
		switch(ev.type){
		/ *
		case "mousedown":
			//this._captureElement = el;
			break;
		case "touchstart":
		case "mousemove":
		case "touchmove":
			break;
		case "mouseup":
		case "touchend":
			if(this._captureElement){
				var listener = runtime._element.data(this._captureElement, "listeners")[ev.type];
				runtime.assert(listener.obj == this._captureElement, "[EventManager::handleEvent]error");
				runtime._task.execute(listener.cbid, [ev]);
				this._captureElement = null;
			}
			break;
		* /
		case runtime.START_EVENT: this.onTouchStart(ev);break;
		case runtime.MOVE_EVENT : this.onTouchMove(ev);break;
		case runtime.END_EVENT  : this.onTouchEnd(ev);break;
		default:
			runtime.error("[EventManager::handleEvent]unsupport event(type=" + ev.type + ")");
			break;
		}
	};
	this.setCapture = function(el){
		runtime.assert(this._captureElement == null, "[EventManager::setCapture]error");
		this._captureElement = el;
	};
	this.releaseCapture = function(el){
		runtime.assert(this._captureElement == el, "[EventManager::releaseCapture]error");
		this._captureElement = null;
	};
	this.onTouchStart = function(ev){
		//ev = ev || window.event;
		var targets = [];
		for(var t = ev.target; t; t = t.parentNode){
			if(t._ptr){
				console.log(t._ptr._className);
				targets.unshift(t._ptr);
			}
		}
		this._down = true;
		//this._move = false;
		for(var i = 0, len = targets.length; i < len; i++){
			if(ev._stopped){
				break;
			}
			if(targets[i].onTouchStart){
				this._activeComponent = targets[i];
				targets[i].onTouchStart(ev);
			}
			//this.handleTarget(targets[i], ev, true);
		}
		for(var i = targets.length - 1; i >= 0; i--){
			if(ev._stopped){
				break;
			}
			if(targets[i].onTouchStart){
				targets[i].onTouchStart(ev);
			}
			//this.handleTarget(targets[i], ev, false);
		}
		this._timer = runtime.startTimer(100, this, function(){
			if(runtime.stopTimer(this._timer)){
				//if(!this._move){
					for(var i = targets.length - 1; i >= 0; i--){
						var target = targets[i];
						if(target.onTabStart){
							target.onTabStart(ev);
						}
					}
				//}
			}
			//listener.touchstart.call(c, ev);
		});
		ev.preventDefault();
		ev.stopPropagation();
	};
	this.onTouchMove = function(ev){
		if(this._down){
			//this._move = true;
			runtime.stopTimer(this._timer);
			//console.log(this._activeComponent);
			if(this._activeComponent && this._activeComponent.onTouchMove){
				return this._activeComponent.onTouchMove(ev);
			}
			//return listener.touchmove.call(c, ev);
		}
	};
	this.onTouchEnd = function(ev){
		var ret;
		var touch = ev.changedTouches ? ev.changedTouches[0] : ev;
		runtime.log(touch.target.tagName + " class=" + touch.target.className);
		//ret = this.dispatchAction(this._self, ev);
		if(this._down){
			//console.log(ev.target);
			if(this._activeComponent && this._activeComponent.onTouchEnd){
				ret = this._activeComponent.onTouchEnd(ev);
				this._activeComponent = null;
			}
			//return listener.touchend.call(c, ev);
			this._down = false;
		}
		//ev.stopPropagation();
		return ret;
	};
	*/
});